package com.gmrz.uaf.db.dao;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.db.DAOException;
import com.gmrz.uaf.protocol.v1.processor.exception.UAFErrorCode;
import com.gmrz.uaf.protocol.v1.schema.WhiteList;
import com.gmrz.util.db.DBUtil;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created by chentaikun on 16/12/26.
 */
public class BaseWhiteListDAO implements WhiteListDAO{

    private static final Logger LOG = LogManager.getLogger(BaseWhiteListDAO.class);
    private Connection conn_;
    public BaseWhiteListDAO(){}
    @AssistedInject
    public BaseWhiteListDAO(@Assisted Connection conn_){
        this.conn_ = conn_;
    }
    private static final String _SQL_LIST = "SELECT wl_id,visit_address,tenant_id FROM t_white_list";

    public List<WhiteList> list() throws DAOException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<WhiteList> list = new ArrayList<WhiteList>();
        try {
            WhiteList whiteList  = null;
            ps = this.conn_.prepareStatement(_SQL_LIST);
            rs = ps.executeQuery();
            while (rs.next()) {
                whiteList = new WhiteList();
                whiteList.setId(rs.getString("wl_id"));
                whiteList.setVisitAddress(rs.getString("visit_address"));
                whiteList.setAppID(rs.getString("tenant_id"));
                list.add(whiteList);
            }
            return list;
        } catch (SQLException exp) {
            LOG.error("The following SQL statement failed to execute :\n {}", _SQL_LIST);
            throw new DAOException(UAFErrorCode.DB_QUERY_WHITE_LIST_FAILED,exp);
        } finally {
            DBUtil.close(ps);
            DBUtil.close(rs);
        }
    }

    private static final String VENDOR_SQL_LIST =   "select b.vendor_name, c.equ_model, v.equ_version  \n" +
                                                    "from t_vendor_allow a \n" +
                                                    "left join t_vendor b on a.ven_id = b.ven_id \n" +
                                                    "left join t_equipment c on a.equ_id = c.equ_id \n" +
                                                    "left join t_equipment_version v on a.equ_version_id = v.equ_version_id \n" +
                                                    "where a.tenant_id = ?";
    @Override
    public Set<String> vendorList(String appID) throws DAOException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Set<String> result = new HashSet<String>();
        try {
            ps = this.conn_.prepareStatement(VENDOR_SQL_LIST);
            ps.setString(1,appID);
            rs = ps.executeQuery();
            StringBuilder strB = new StringBuilder();
            while (rs.next()) {
                strB.append(rs.getString("vendor_name").trim());
                strB.append(Constants.UAF_FORBID_ALLOW_CONCAT_SPLIT);
                if (rs.getString("equ_model") == null){
                    strB.append(Constants.UAF_FORBID_ALLOW_CONCAT);
                }else {
                    strB.append(rs.getString("equ_model").trim());
                }
                strB.append(Constants.UAF_FORBID_ALLOW_CONCAT_SPLIT);
                if (rs.getString("equ_version") == null){
                    strB.append(Constants.UAF_FORBID_ALLOW_CONCAT);
                }else {
                    strB.append(rs.getString("equ_version").trim());
                }
                result.add(strB.toString());
                strB.delete(0, strB.length());
            }
            return result;
        } catch (SQLException exp) {
            LOG.error("The following SQL statement failed to execute :\n {}", VENDOR_SQL_LIST);
            throw new DAOException(UAFErrorCode.DB_QUERY_VENDOR_LIST_FAILED,exp);
        } finally {
            DBUtil.close(ps);
            DBUtil.close(rs);
        }
    }
    private static final String EQUIPMENT_SQL_LIST = "select b.vendor_name, c.equ_model, v.equ_version  \n" +
                                                     "from t_equipment_forbid a \n" +
                                                     "left join t_vendor b on a.ven_id = b.ven_id \n" +
                                                     "left join t_equipment c on a.equ_id = c.equ_id \n" +
                                                     "left join t_equipment_version v on a.equ_version_id = v.equ_version_id \n" +
                                                     "where a.tenant_id = ? ";
    @Override
    public Set<String> equipmentList(String appID) throws DAOException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Set<String> result = new HashSet<String>();
        try {
            ps = this.conn_.prepareStatement(EQUIPMENT_SQL_LIST);
            ps.setString(1,appID);
            rs = ps.executeQuery();
            StringBuilder strB = new StringBuilder();
            while (rs.next()) {
                strB.append(rs.getString("vendor_name").trim());
                strB.append(Constants.UAF_FORBID_ALLOW_CONCAT_SPLIT);
                if(rs.getString("equ_model") == null){
                    strB.append(Constants.UAF_FORBID_ALLOW_CONCAT);
                }else {
                    strB.append(rs.getString("equ_model").trim());
                }
                strB.append(Constants.UAF_FORBID_ALLOW_CONCAT_SPLIT);
                if(rs.getString("equ_version") == null){
                    strB.append(Constants.UAF_FORBID_ALLOW_CONCAT);
                }else {
                    strB.append(rs.getString("equ_version").trim());
                }
                result.add(strB.toString());
                strB.delete(0, strB.length());
            }
            return result;
        } catch (SQLException exp) {
            LOG.error("The following SQL statement failed to execute :\n {}", EQUIPMENT_SQL_LIST);
            throw new DAOException(UAFErrorCode.DB_QUERY_EQUIPMENT_LIST_FAILED,exp);
        } finally {
            DBUtil.close(ps);
            DBUtil.close(rs);
        }
    }

    private static final String DEVICEIDFORBID_SQL_LIST = " select device_id from t_device_forbid where tenant_id = ?";
    @Override
    public Set<String> getDeviceIdForbidList(String appID) throws DAOException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Set<String> result = new HashSet<String>();
        try {
            ps = this.conn_.prepareStatement(DEVICEIDFORBID_SQL_LIST);
            ps.setString(1,appID);
            rs = ps.executeQuery();
            while (rs.next()) {
                result.add(rs.getString("device_id").trim());
            }
            return result;
        } catch (SQLException exp) {
            LOG.error("The following SQL statement failed to execute :\n {}", DEVICEIDFORBID_SQL_LIST);
            throw new DAOException(UAFErrorCode.DB_QUERY_DEVICEID_LIST_FAILED,exp);
        } finally {
            DBUtil.close(ps);
            DBUtil.close(rs);
        }
    }

    private static final String EQUIPMENT_VERSION_SQL_LIST = "SELECT ev.equ_version from t_equipment_version ev join t_equipment e on ev.equ_id = e.equ_id WHERE e.equ_model = ?";
    @Override
    public Set<String> getEquipmentVersion(String deviceName) throws DAOException {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Set<String> result = new HashSet<String>();
        try {
            ps = this.conn_.prepareStatement(EQUIPMENT_VERSION_SQL_LIST);
            ps.setString(1,deviceName);
            rs = ps.executeQuery();
            while (rs.next()) {
                result.add(rs.getString("equ_version").trim());
            }
            return result;
        } catch (SQLException exp) {
            LOG.error("The following SQL statement failed to execute :\n {}", EQUIPMENT_SQL_LIST);
            throw new DAOException(UAFErrorCode.DB_QUERY_EQUIPMENT_LIST_FAILED,exp);
        } finally {
            DBUtil.close(ps);
            DBUtil.close(rs);
        }
    }
}
